﻿using Pdf2epub.Interfaces;
using Pdf2epub.Model;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;

namespace Pdf2epub.UI
{
    /// <summary>
    /// Interaction logic for StyleEditor.xaml
    /// </summary>
    public partial class StyleEditor
    {
        private IProjectContext m_ProjectContext;

        public StyleEditor()
        {
            InitializeComponent();
        }

        public HtmlReplacementCollection AvailableStyles
        {
            get
            {
                if (ProjectContext == null)
                    return null;
                return ProjectContext.ProjectConfiguration.HtmlReplacements;
            }
        }

        public IProjectContext ProjectContext
        {
            get { return m_ProjectContext; }
            set
            {
                m_ProjectContext = value;
                LvAvailableStyles.ItemsSource = AvailableStyles;
            }
        }

        #region Command Handling

        private void OnCanExecuteAddNewStyle(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void OnCanExecuteRemoveSelectedStyle(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ((LvAvailableStyles != null) && (LvAvailableStyles.SelectedItem != null));
        }

        private void OnCommandExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command is RoutedUICommand)
            {
                RoutedUICommand uiCommand = e.Command as RoutedUICommand;
                switch (uiCommand.Name)
                {
                    case "AddNewStyle":
                        AddNewStyle();
                        break;

                    case "RemoveSelectedStyle":
                        RemoveSelectedStyle();
                        break;
                }
            }
        }

        #endregion Command Handling

        private static string RenderDemoHtml(HtmlReplacement htmlReplacement)
        {
            XmlDocument xmlDoc = new XmlDocument();

            XmlElement htmlElement = xmlDoc.CreateElement("html");
            XmlNode htmlNode = xmlDoc.AppendChild(htmlElement);

            XmlElement headerElement = xmlDoc.CreateElement("head");
            XmlNode headerNode = htmlNode.AppendChild(headerElement);

            XmlElement styleDefinitionElement = xmlDoc.CreateElement("style");
            styleDefinitionElement.SetAttribute("type", "text/css");
            string styleDefinition = string.Format("{0} {1}\n", htmlReplacement.StyleName, htmlReplacement.StyleContent);

            XmlText styleTextElement = xmlDoc.CreateTextNode(styleDefinition);
            styleDefinitionElement.AppendChild(styleTextElement);
            headerNode.AppendChild(styleDefinitionElement);

            XmlElement bodyElement = xmlDoc.CreateElement("body");
            XmlNode bodyNode = htmlNode.AppendChild(bodyElement);

            XmlElement para = xmlDoc.CreateElement(htmlReplacement.Tag.ToString());
            bodyNode.AppendChild(para);

            XmlElement span = xmlDoc.CreateElement("span");
            span.SetAttribute("class", htmlReplacement.StyleName.TrimStart('.'));
            para.AppendChild(span);

            XmlText text =
                xmlDoc.CreateTextNode(
                    "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
            para.AppendChild(text);

            string html = xmlDoc.InnerXml;
            return html;
        }

        private void AddNewStyle()
        {
            HtmlReplacement replacement = new HtmlReplacement { StyleName = ".newStyle" };
            replacement.SetProjectContext(ProjectContext);

            ProjectContext.ProjectConfiguration.HtmlReplacements.Add(replacement);
        }

        private void ClearPreviewBrowser()
        {
            if (WebPreview != null)
            {
                WebPreview.Navigate("about:blank");
            }
        }

        private void OnAvailableStylesSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            PgStyleDetails.SelectedObject = LvAvailableStyles.SelectedItem;

            RenderPreviewForSelectedReplacement();
        }

        private void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            RenderPreviewForSelectedReplacement();
        }

        private void RemoveSelectedStyle()
        {
            HtmlReplacement replacement = LvAvailableStyles.SelectedItem as HtmlReplacement;
            if (replacement == null)
                return;

            if (MessageBox.Show(this,
                string.Format("Really remove style '{0}'", replacement.StyleName),
                "Remove style",
                MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No)
                return;

            ProjectContext.ProjectConfiguration.HtmlReplacements.Remove(replacement);
        }

        private void RenderPreviewForSelectedReplacement()
        {
            HtmlReplacement htmlReplacement = LvAvailableStyles.SelectedItem as HtmlReplacement;
            if (htmlReplacement == null)
            {
                ClearPreviewBrowser();
                return;
            }

            WebPreview.NavigateToString(RenderDemoHtml(htmlReplacement));
        }
    }
}